﻿// pch.h: 这是预编译标头文件。
// 下方列出的文件仅编译一次，提高了将来生成的生成性能。
// 这还将影响 IntelliSense 性能，包括代码完成和许多代码浏览功能。
// 但是，如果此处列出的文件中的任何一个在生成之间有更新，它们全部都将被重新编译。
// 请勿在此处添加要频繁更新的文件，这将使得性能优势无效。

#ifndef PCH_H
#define PCH_H



// 添加要在此处预编译的标头
#include "framework.h"
#include <vector>
#include <Windows.h>
#include <string>

#define Efi_GetEfiPartitionInfoTable Efi_GetEfiPartitionInfoTableW
#define Esp_GetEfiPartitionInfoTable Efi_GetEfiPartitionInfoTableW
#define Esp_GetEfiPartitionInfoTableW Efi_GetEfiPartitionInfoTableW
#define Esp_GetEfiPartitionInfoTableA Efi_GetEfiPartitionInfoTableA

//错误代码
#define ERROR_GETDRVINFO_NODISK 1						//计算机中没有磁盘
#define ERROR_GETDRVINFO_OPEN_DISK_FAIL 2				//通过CreateFile打开磁盘失败
#define ERROR_GETDRVINFO_GET_STRUCT_SIZE_FAIL 3			//获取结构体大小失败
#define ERROR_GETDRVINFO_GET_STRUCT_FAIL 4				//获取结构体失败

#define ERROR_GETVOLUME_GET_VOLUME_MOUNT_PATH_FAIL 5	//获取卷挂载路径失败
#define ERROR_GETESPINFO_NO_ESP_PARTITION 6				//没有ESP分区
#define ERROR_GETESPINFO_NO_MORE_AVAIBLE_LETTER 7		//没有多余盘符(获取可用盘符)
#define ERROR_MOUNTESP_NO_MORE_AVAIBLE_LETTER 8			//没有多余盘符(挂载ESP)

/// <summary>
/// EFI分区信息表(wchar_t型)
/// </summary>
typedef struct EFI_PARTITION_INFOMATION_W {
	int DiskNumber;					//EFI分区所在硬盘编号，从0开始
	
	std::wstring PartionDrivePathW;	//分区路径，如"\\Device\\Harddisk0\\Partition1"，可通过该路径挂载和卸载EFI分区

	bool HasPartitionLetter;		//分区是否被挂载
	char PartitionLetter;			//分区卷标，若HasPartitionLetter为false则为NULL
};

/// <summary>
/// EFI分区信息表(char型)
/// </summary>
typedef struct EFI_PARTITION_INFOMATION_A {
	int DiskNumber;					//EFI分区所在硬盘编号，从0开始

	std::string PartionDrivePathA;	//分区路径，如"\\Device\\Harddisk0\\Partition1"，可通过该路径挂载和卸载EFI分区

	bool HasPartitionLetter;		//分区是否被挂载
	char PartitionLetter;			//分区卷标，若HasPartitionLetter为false则为NULL
};

/// <summary>
/// 挂载所有EFI分区，已挂载的分区不会重复挂载
/// </summary>
/// <param name="MountedEspLetter">指向用于接收挂载的ESP分区盘符的指针</param>
/// <returns>成功返回1，失败返回0，可使用GetLastError获取错误信息</returns>
BOOL Esp_MountEfiPartition(_Out_ std::vector<char>* MountedEspLetter);

/// <summary>
/// 挂载指定硬盘编号的EFI分区，已挂载的不会重新挂载
/// </summary>
/// <param name="DiskNumber">硬盘号，从0开始</param>
/// <param name="MountedEspLetter">指向用于接收挂载的EFI分区盘符的指针</param>
/// <returns>成功返回1，失败返回0，可使用GetLastError获取错误信息</returns>
BOOL Esp_MountEfiPartition(_In_ int DiskNumber, _Out_ std::vector<char>* MountedEspLetter);

/// <summary>
/// 卸载所有EFI分区，已卸载的不会重复卸载
/// </summary>
/// <param name="UnmountedEspLetter">指向用于接收卸载的EFI分区盘符的指针</param>
/// <returns>成功返回1,失败返回0，可使用GetLastError获取错误信息</returns>
BOOL Esp_UnmountEfiPartition(_Out_ std::vector<char>* UnmountedEspLetter);

/// <summary>
/// 卸载指定EFI分区，已卸载的不会重复卸载
/// </summary>
/// <param name="Letter">盘符，例如"C","D"，字母必须大写</param>
/// <returns>成功返回1，失败返回0,可使用GetLastError获取错误信息</returns>
BOOL Esp_UnmountEfiPartition(_In_ char Letter);

/// <summary>
/// 卸载指定硬盘编号的EFI分区，已卸载的不会重新卸载
/// </summary>
/// <param name="DiskNumber">硬盘号，从0开始</param>
/// <param name="UnmountedEspLetter">指向用于接收卸载的EFI分区盘符的指针</param>
/// <returns>成功返回1,失败返回0，可使用GetLastError获取错误信息/returns>
BOOL Esp_UnmountEfiPartition(_In_ int DiskNumber, _Out_ std::vector<char>* UnmountedEspLetter);

/// <summary>
/// 获取计算机上所有EFI分区信息(char型)
/// </summary>
/// <param name="PartitionInfo">指向用于接收EFI分区信息的列表的指针</param>
/// <returns>成功返回1，失败返回0，可用GetLastError获取错误信息</returns>
BOOL Efi_GetEfiPartitionInfoTableA(
	_Out_ std::vector<EFI_PARTITION_INFOMATION_A*>* PartitionInfo
);

/// <summary>
/// 获取计算机上所有EFI分区信息(wchar_t型)
/// </summary>
/// <param name="PartitionInfo">指向用于接收EFI分区信息的列表的指针</param>
/// <returns>成功返回1，失败返回0，可用GetLastError获取错误信息</returns>
BOOL Efi_GetEfiPartitionInfoTableW(
	_Out_ std::vector<EFI_PARTITION_INFOMATION_W*>* PartitionInfo
);

/// <summary>
/// 挂载所有EFI分区，已挂载的分区不会重复挂载(输出字符串)
/// </summary>
/// <returns>成功返回std::string，失败报错，可用GetLastError获取错误信息</returns>
std::string Esp_MountEfiPartitionString();

/// <summary>
/// 挂载指定硬盘编号的EFI分区，已挂载的不会重新挂载(输出字符串)
/// </summary>
/// <param name="DiskNumber">硬盘号，从0开始</param>
/// <returns>成功返回std::string，失败报错，可使用GetLastError获取错误信息</returns>
std::string Esp_MountEfiPartitionString(int DiskNumber);

/// <summary>
/// 卸载所有EFI分区，已卸载的分区不会重复卸载(输出字符串)
/// </summary>
/// <returns>成功返回std::string，失败报错，可用GetLastError获取错误信息</returns>
std::string Esp_UnmountEfiPartitionString();

/// <summary>
/// 卸载指定EFI分区，已卸载的不会重复卸载
/// </summary>
/// <param name="Letter">盘符，例如"C","D"，字母必须大写</param>
/// <returns>成功返回std::string，失败报错，可用GetLastError获取错误信息</returns>
std::string Esp_UnmountEfiPartitionString(char Letter);

/// <summary>
/// 卸载指定硬盘编号的EFI分区，已卸载的不会重新卸载(输出字符串)
/// </summary>
/// <param name="DiskNumber">硬盘号，从0开始</param>
/// <returns>成功返回1,失败返回0，可使用GetLastError获取错误信息</returns>
std::string Esp_UnmountEfiPartitionString(int DiskNumber);

#endif //PCH_H
